dofile("mov.lua")

function onCollision(omov,obs,nx,ny)
  local cresult = 1
  local sresult = 1

  if (obs.id==3) and (ny==1) then
    cresult = 0
  else
    if nx==-1 then
      if obs.id==2 then
        omov.nextGrav=-32
      end
    elseif nx==0 then
      omov.grav=0
      if ny==-1 then
        omov.jump=0
      end
    elseif ny<0 then
      omov.grav=0
      omov.jump=0
--desabilita "escorregar" por gravidade em ladeiras
      if omov.vel.x==0 then sresult=0 end
    elseif ny>0 then
--      if omov.vel.y<0 then omov.grav=0 end
    end
  end

  return cresult,sresult
end

local hscreenw = SCREEN_WIDTH/2
local hscreenh = SCREEN_HEIGHT/2
local tilew = 32
local tileh = 32
local whitec = Color.new(31,31,31)

local function createP()
--  local p = newRectObj(0,-7,-14,7,14)
  local p = newCircleObj(0,0,2,12)
  p.width=24
  p.height=32
  
  p.hw=p.width/2
  p.hh=p.height/2
  p.x=0
  p.y=0
  p.vel={}
  p.vel.x=0
  p.vel.y=0
  p.grav=0
  p.nextGrav=0
  p.jump=0

  p.spr = Sprite.new("sprite.png", p.width, p.height, VRAM)
  p.spr:addAnimation({0,1,2,1},100)
  p.spr:addAnimation({3,4,5,4},100)
  p.spr:addAnimation({6,7,8,7},100)
  p.spr:addAnimation({9,10,11,10},100)

  p.dir = 1

  return p
end

local function deleteP(p)
  p.d=nil
  p.vel=nil

  p.spr:destroy()
  p.spr=nil
end

local p = createP()
local obs = {}
obs[1]=newRectObj(1,40,-10,50,10)
obs[2]=newRectObj(3,-100,-30,100,-25)
obs[3]=newRectObj(1,-100,80,100,100)
obs[4]=newRectObj(2,50,75,100,80)
obs[5]=newRectObj(2,70,70,100,75)
obs[6]=newRectObj(1,-100,20,-70,75)
obs[7]=newLineObj(1,-100,-100,-10,-10)
obs[8]=newLineObj(1,-100,-100,-160,-130)
obs[9]=newLineObj(1,-160,-130,-200,-140)


local i
local cmapw=60
local cmaph=60
local cmaptsz = 16
local invcmaptsz = 1/cmaptsz
local cmap = {}
for i=1,cmaph do
  local j
  cmap[i]={}
  for j=1,cmapw do
    cmap[i][j]=0
  end
end
cmap[3][1]=1
cmap[4][1]=1
cmap[5][1]=1
cmap[6][1]=1
cmap[7][1]=1

for i=1,cmapw/2 do
  cmap[8][i]=1
end

for i=2+cmapw/2,cmapw do
  cmap[9][i]=1
end

im = Image.load("tiles.png", VRAM)
map = ScrollMap.new(im, "map.map", 15, 15, tilew, tileh)

Map.setTile(map, 0, 0, 0)

while not Keys.newPress.Start do
  Controls.read()
  local v=50
  local time=0.03333

  p.grav = p.grav+10
  p.vel.x=0
  p.vel.y=0
  if Keys.held.A then
    v=80
  end

  if p.nextGrav~=0 then
    p.grav = p.nextGrav
    p.nextGrav = 0
  end
  if Keys.newPress.B and p.jump<2 then
    p.grav=-180
    p.jump=p.jump+1
  end
  if Keys.held.Up then
    p.vel.y = -v
    p.dir=1
  end
  if Keys.held.Down then
    p.vel.y = v
    p.dir=3
  end
  if Keys.held.Left then
    p.vel.x = -v
    p.dir=4
  end
  if Keys.held.Right then
    p.vel.x = v
    p.dir=2
  end

  p.vel.y=p.vel.y+p.grav
  local mx = p.hw+math.abs(p.vel.x*time)
  local my = p.hh+math.abs(p.vel.y*time)
  local tamMov = math.sqrt(mx*mx+my*my)
  local cx1 = p.x-tamMov
  local cy1 = p.y-tamMov
  local cx2 = p.x+tamMov
  local cy2 = p.y+tamMov
  
  local tamMovTiles = 1+math.floor(tamMov/cmaptsz)
  local tx = math.floor(1+p.x/cmaptsz)
  local ty = math.floor(1+p.y/cmaptsz)
  local cx1t = tx-tamMovTiles
  local cx2t = tx+tamMovTiles
  local cy1t = ty-tamMovTiles
  local cy2t = ty+tamMovTiles
  
  if cx1t<1 then cx1t = 1 end
  if cx2t>cmapw then cx2t = cmapw end
  if cy1t<1 then cy1t = 1 end
  if cy2t>cmaph then cy2t = cmaph end

  local cobs = {}

  local y2 = cy1t*cmaptsz
  local y1 = y2-cmaptsz
  for i=cy1t,cy2t do
    local j
    local crow = cmap[i]
    local x2 = cx1t*cmaptsz
    local x1 = x2-cmaptsz
    for j=cx1t,cx2t do
      if crow[j]==1 then
        if collisionRR(cx1,cy1,cx2,cy2,x1,y1,x2,y2) then
          cobs[#cobs+1]=newRectObj(1,x1,y1,x2,y2)
        end
      end
      x1 = x2
      x2 = x2+cmaptsz
    end
    y1 = y2
    y2 = y2+cmaptsz
  end
  
  for i=1,#obs do
    if obs[i].type==T_RECT then
      if collisionRR(cx1,cy1,cx2,cy2,obs[i].d.minx,obs[i].d.miny,obs[i].d.maxx,obs[i].d.maxy) then
        cobs[#cobs+1]=obs[i]
      end
    elseif obs[i].type==T_LINE then
      local xmin,xmax,ymin,ymax
      if obs[i].d.p1.x<obs[i].d.p2.x then
        xmin=obs[i].d.p1.x
        xmax=obs[i].d.p2.x
      else
        xmin=obs[i].d.p2.x
        xmax=obs[i].d.p1.x
      end
      if obs[i].d.p1.y<obs[i].d.p2.y then
        ymin=obs[i].d.p1.y
        ymax=obs[i].d.p2.y
      else
        ymin=obs[i].d.p2.y
        ymax=obs[i].d.p1.y
      end
      if collisionRR(cx1,cy1,cx2,cy2,xmin,ymin,xmax,ymax) then
        cobs[#cobs+1]=obs[i]        
      end
    end
  end

  ScrollMap.scroll(map, p.x-hscreenw, p.y-hscreenh)
  ScrollMap.draw(SCREEN_DOWN,map)

  p.spr:playAnimation(SCREEN_DOWN, hscreenw-p.hw, hscreenh-p.hh, p.dir)

  local i
  for i=1,#cobs do
    if cobs[i].type==T_RECT then
      screen.drawRect(SCREEN_DOWN, cobs[i].d.minx+hscreenw-p.x, cobs[i].d.miny+hscreenh-p.y, cobs[i].d.maxx-p.x+hscreenw, cobs[i].d.maxy-p.y+hscreenh,whitec)
    elseif cobs[i].type==T_LINE then
      screen.drawLine(SCREEN_DOWN, cobs[i].d.p1.x+hscreenw-p.x, cobs[i].d.p1.y+hscreenh-p.y, cobs[i].d.p2.x-p.x+hscreenw, cobs[i].d.p2.y-p.y+hscreenh,whitec)
    end
  end
  screen.drawRect(SCREEN_DOWN, cx1+hscreenw-p.x, cy1+hscreenh-p.y, cx2-p.x+hscreenw, cy2-p.y+hscreenh,whitec)

  local des = mov(p,cobs,time,onCollision)
  p.x = p.x+des.x
  p.y = p.y+des.y

  screen.print(SCREEN_UP, 0, 0, "+ to scroll: ")
  screen.print(SCREEN_UP, 0, 16, "Pres START to quit")
  screen.print(SCREEN_DOWN, 0, 184, "FPS: "..NB_FPS)

  render()
end

Image.destroy(im)
im = nil
ScrollMap.destroy(map)
map = nil

deleteP(p)
p=nil

local n=#obs
for i=1,n do
  obs[i].d=nil
  obs[i]=nil
end
obs=nil

--os.exit()

